/****************************************************************************
 * Copyright (c) 2024 Qualcomm Technologies International, Ltd.
****************************************************************************/
/**
 * \file     basic_passthrough_thread_private.c
 * \ingroup  operators
 *
 *  Basic passthrough operator
 *
 */

#ifdef INSTALL_SUB_TASK_API /* Entire file is guarded for x2p compilation */

/****************************************************************************
Include Files
*/
#include "capabilities.h"
#include "basic_passthrough_private.h"
#include "basic_passthrough_thread_private.h"
#include "basic_passthrough_gen_c.h"
#include "dls_kymera_util_if.h"

/****************************************************************************
Private Constant Definitions
*/


/****************************************************************************
Private Type Definitions
*/

void init_pass_through_threads_(BASIC_PASSTHROUGH_OP_DATA *opx_data)
{
    opx_data->passThroughTimerTaskId = 0;
    opx_data->isTaskCreated = 0;
    opx_data->frameCounter = 0;
    for(int i =0 ; i<MAX_SUB_TASK; i++)
    {
        opx_data->subTaskID[i] = 0;
    }
    opx_data->sub_task_context = NULL;
}

void destroy_pass_through_threads_(BASIC_PASSTHROUGH_OP_DATA *opx_data)
{
    if (opx_data->isTaskCreated)
    {
        for(int i =0 ; i<MAX_SUB_TASK; i++)
        {
            if(opx_data->subTaskID[i] != 0 )
            {
                delete_task(opx_data->subTaskID[i]);
                opx_data->subTaskID[i] = 0;
            }
        }
        timer_cancel_event(opx_data->passThroughTimerTaskId);
        opx_data->passThroughTimerTaskId = 0;
        opx_data->isTaskCreated = 0;
        opx_data->frameCounter = 0;

    }
    if (NULL != opx_data->sub_task_context)
    {
        pfree(opx_data->sub_task_context);
        opx_data->sub_task_context = NULL;
    }   
}

void create_pass_through_threads_(BASIC_PASSTHROUGH_OP_DATA *opx_data)
{
    taskid taskid_in_passthru ;
    if (!opx_data->isTaskCreated)
    {
        L2_DBG_MSG(" THREAD_PRIVATE sub task creating --- \n");
        opx_data->sub_task_context = (SUBTASK_CONTEXT*) xpmalloc(sizeof(SUBTASK_CONTEXT));
        taskid_in_passthru = task_mgr_create_task(LOWEST_PRIORITY, (void*)opx_data, SUB_TASK_0);
        opx_data->subTaskID[0] = taskid_in_passthru;
        taskid_in_passthru = task_mgr_create_task(MID_PRIORITY, (void*)opx_data, SUB_TASK_1);
        opx_data->subTaskID[1] = taskid_in_passthru;
        taskid_in_passthru = task_mgr_create_task(HIGHEST_PRIORITY, (void*)opx_data, SUB_TASK_2);
        opx_data->subTaskID[2] = taskid_in_passthru;
        L2_DBG_MSG3(" BASIC_PASSTHRU:::: sub task created 0x%x 0x%x 0x%x\n", opx_data->subTaskID[0], opx_data->subTaskID[1], opx_data->subTaskID[2]);

        TIME current_time = time_get_time();
        opx_data->passThroughTimerTaskId = timer_schedule_event_at(current_time + 1000, basic_passthrough_timer_task, opx_data);

        opx_data->isTaskCreated = 1;
    }
}

void process_pass_through_threads_(BASIC_PASSTHROUGH_OP_DATA *opx_data)
{
    if (opx_data->isTaskCreated)
    {
        opx_data->frameCounter++;
        
        for(int task_cnt =0 ; task_cnt < MAX_SUB_TASK; task_cnt++)
        {
            if(opx_data->subTaskID[task_cnt] != 0 )
            {
                put_message(opx_data->subTaskID[task_cnt], 0, NULL);
            }
        }
        for(int task_cnt =0 ; task_cnt < MAX_SUB_TASK; task_cnt++)
        {
            if(opx_data->subTaskID[task_cnt] != 0 )
            {
                raise_bg_int(opx_data->subTaskID[task_cnt]);
            }
        }        

        if (opx_data->frameCounter < 100)
        {
            L2_DBG_MSG3(" THREAD_PRIVATE BASIC_PASSTHRU:::: sub task created 0x%x 0x%x 0x%x\n", opx_data->subTaskID[0], opx_data->subTaskID[1], opx_data->subTaskID[2]);
        }
    }
}

void print_render_info_(bool enable)
{
    //L2_DBG_MSG1(":::::print_render_info_ time = %u", time_get_time());
    L2_DBG_MSG("\n");
    if (enable)
    {
        EP_TOD_STATS_INFO_LIST sinkRenderInfoFromPatch;
        bool status = ep_tod_stats_get(&sinkRenderInfoFromPatch);
        unsigned num_elements = sinkRenderInfoFromPatch.num_elements;
        
        //L2_DBG_MSG1(":::::print_render_info_   num_elements = %u", num_elements);
        if (status)
        for (int i=0; i < num_elements; ++i)
        {
            L2_DBG_MSG2("Index = %d status = %u", i, status);
            L2_DBG_MSG5("THREAD_PRIVATE_ INSIDE PROCESS ::: sinkRenderInfoFromPatch time=%u samples = %u ep_id=0x%x ep_hw_latency=%u ep_mmu_buf_size = %u", 
                                                                                                                 sinkRenderInfoFromPatch.stats_info[i].ep_tod,
                                                                                                                 sinkRenderInfoFromPatch.stats_info[i].ep_acc_samples,
                                                                                                                 sinkRenderInfoFromPatch.stats_info[i].ep_id,
                                                                                                                 sinkRenderInfoFromPatch.stats_info[i].ep_hw_latency,
                                                                                                                 sinkRenderInfoFromPatch.stats_info[i].ep_mmu_buf_size);
        }
    }
}

#endif /* INSTALL_SUB_TASK_API */
